{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import ipywidgets as widgets"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Password generator: `observe`\n",
    "\n",
    "Consider a super-simple (and super-bad) password generator widget: given a password length, represented by a slider in the interface, it constructs a sequence of random letters of that length and displays it. \n",
    "\n",
    "\n",
    "This notebook illustrates how to connect the function that calculates the password to the length slider using `observe` but mixes together the code to calculate the password and the code to handle the events generated by the interface"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Construct the interface (widget)\n",
    "\n",
    "The widget should look like this once constructed:\n",
    "\n",
    "![Password generator](images/bad-pass-gen-v1.png)\n",
    "\n",
    "Compose the widget out of three basic widgets, one each for the title, the (currently not set) password, and one for the slider. \n",
    "\n",
    "In the cell below construct each of the basic widgets. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "helpful_title = 0  # Replace with some that displays \"Generated password is:\"\n",
    "password_text = 0  # Replace with something that displays \"No password set\"\n",
    "password_length = 0 # Replace with slider\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Combine these three into a single widget...the output should look like the image above."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "password_widget = widgets.VBox(children=[helpful_title, password_text, password_length])\n",
    "password_widget"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# %load solutions/bad-password-generator/bad-pass-pass1-widgets.py\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Calculate the password...\n",
    "\n",
    "The function below calculates the password and should set the value of the `password_text` widget. The first part has been done, you just need to add the line that sets the widget value."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def calculate_password(change):\n",
    "    import string\n",
    "    from secrets import choice\n",
    "    length = change.new\n",
    "    # Generate a list of random letters of the correct length.\n",
    "    password = ''.join(choice(string.ascii_letters) for _ in range(length))\n",
    "    # Add a line below to set the value of the widget password_text\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# %load solutions/bad-password-generator/bad-pass-pass1-passgen.py\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## ...and link password to widgets\n",
    "\n",
    "Fill in the line below. You want `calculate_password` to be called when the value of `password_length` changes. Here is a link to [Widget Events](06-Widget_Events.ipynb) in case you need it."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# call calculate_password whenever the password length changes\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# %load solutions/bad-password-generator/bad-pass-pass1-observe.py"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now that the connection is made, try moving the slider and you should see the password update."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "widgets-tutorial",
   "language": "python",
   "name": "widgets-tutorial"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
